﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web.Configuration;
using System.Web.Mvc;
using ImageCropper.Web.ViewModels;

namespace ImageCropper.Web.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult EditImage(string imageUrl, string savePath)
        {
            var request = WebRequest.Create("http://" + imageUrl);
            Image img;
            using (var response = request.GetResponse())
            {
                using (var stream = response.GetResponseStream())
                {
                    if (stream == null)
                    {
                        return RedirectToAction("ImageUnavailable");
                    }
                    img = Image.FromStream(stream);
                }
            }
            var imageName = imageUrl.Split('/').Last().Split('.').First();
            var uniqueID = Convert.ToBase64String(Encoding.ASCII.GetBytes(imageUrl));
            var imageNameUnique = imageName + "_" + uniqueID;
            var tempFolder = WebConfigurationManager.AppSettings["TempFolder"];
            var savePathTemp = Server.MapPath(string.Format("/{0}/", tempFolder));
            var imageExtension = imageUrl.Split('.').Last();
            img.Save(string.Format("{0}{1}.{2}",savePathTemp, imageNameUnique, imageExtension) );
            if (Request.Url == null)
            {
                throw new Exception("Request has no URL.");
            }
            var model = new EditorModel
                            {
                                ImageUrlTemp = string.Format("http://{0}:{1}/{2}/{3}.{4}", Request.Url.Host, Request.Url.Port, tempFolder, imageNameUnique, imageExtension),
                                SavePath = savePath.Replace(@"\", @"\\"),
                                ImageName = imageName,
                                ImageNameUnique = imageNameUnique,
                                ImageUrl = "http://" + imageUrl,
                                SavePathTemp = savePathTemp.Replace(@"\", @"\\"),
                                OriginalWidth = img.Width,
                                OriginalHeight = img.Height,
                                ImageExtension = imageExtension
                            };
            Session["TempFolder"] = savePathTemp;
            Session["FileNameWithExtension"] = model.ImageNameUnique + "." + model.ImageExtension;
            return View(model);
        }

        [HttpPost]
        public ActionResult Crop(EditorModel model, int height, int width, int x = 0, int y = 0)
        {
            var request = WebRequest.Create(model.ImageUrlTemp);
            Image img;
            using (var response = request.GetResponse())
            {
                using (var stream = response.GetResponseStream())
                {
                    if (stream == null)
                    {
                        return Fail();
                    }
                    img = Image.FromStream(stream);
                }
            }
            var bmpImage = new Bitmap(img);
            img.Dispose();
            var cropRect = new Rectangle(x, y, width, height);
            var croppedBmpImage = bmpImage.Clone(cropRect, PixelFormat.Format24bppRgb);
            var tempFolder = WebConfigurationManager.AppSettings["TempFolder"];
            SaveJpg(string.Format(@"{0}.{1}", Path.Combine(Server.MapPath(string.Format("/{0}", tempFolder)), model.ImageNameUnique), model.ImageExtension), croppedBmpImage);
            ViewBag.Cropped = true;
            return Success();
        }

        [HttpPost]
        public ActionResult Resize(EditorModel model, int height, int width)
        {
            var request = WebRequest.Create(model.ImageUrlTemp);
            Image img;
            using (var response = request.GetResponse())
            {
                using (var stream = response.GetResponseStream())
                {
                    if (stream == null)
                    {
                        return Fail();
                    }
                    img = Image.FromStream(stream);
                }
            }
            var resizedImg = new Bitmap(width, height);
            using (var graphics = Graphics.FromImage(resizedImg))
            {

                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.DrawImage(img, 0, 0, width, height);
            }
            var tempFolder = WebConfigurationManager.AppSettings["TempFolder"];
            SaveJpg(string.Format(@"{0}.{1}", Path.Combine(Server.MapPath(string.Format("/{0}", tempFolder)), model.ImageNameUnique), model.ImageExtension), resizedImg);
            return Success();
        }

        [HttpPost]
        public ActionResult Save(EditorModel model)
        {
            var request = WebRequest.Create(model.ImageUrlTemp);
            Image img;
            using (var response = request.GetResponse())
            {
                using (var stream = response.GetResponseStream())
                {
                    if (stream == null)
                    {
                        return Fail();
                    }
                    img = Image.FromStream(stream);
                }
            }
            SaveJpg(string.Format(@"{0}.{1}", Path.Combine(model.SavePath, model.ImageName), model.ImageExtension), img);
            return Success();
        }

        public ActionResult ImageUnavailable()
        {
            return View();
        }

        private static void SaveJpg(string path, Image image)
        {
            image.Save(path);
        }
        
        private ActionResult Success()
        {
            return Json(new {isOkay = true});
        }

        private ActionResult Fail()
        {
            return Json(new {isOkay = false});
        }

        public ActionResult About()
        {
            return View();
        }
    }
}
